package com.shanzmoo.admin.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shanzmoo.admin.util.SecurityUtil;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.base.constant.Constant;
import com.shanzmoo.base.exception.OutletBusinessException;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.core.domain.UserSaveDto;
import com.shanzmoo.core.util.BCryptUtils;
import com.shanzmoo.db.sys.entity.OutletInfoEntity;
import com.shanzmoo.db.sys.entity.UserEntity;
import com.shanzmoo.db.sys.entity.dto.UserOutletSaveDto;
import com.shanzmoo.db.sys.entity.dto.UserQueryDto;
import com.shanzmoo.core.domain.UserUpdateDto;
import com.shanzmoo.db.sys.entity.dto.UserUpdatePasswordDto;
import com.shanzmoo.db.sys.entity.vo.UserPageVo;
import com.shanzmoo.db.sys.entity.vo.UserPermissionDto;
import com.shanzmoo.db.sys.entity.vo.UserPermissionVo;
import com.shanzmoo.db.sys.entity.vo.UserSelectVo;
import com.shanzmoo.db.sys.service.IOutletInfoService;
import com.shanzmoo.db.sys.service.IUserRoleService;
import com.shanzmoo.db.sys.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author： Gzhao 2021/1/31
 */
@Slf4j
@Component
public class SysUserManager {

    @Autowired
    private IUserService userService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IOutletInfoService outletInfoService;

    @Transactional(rollbackFor = Throwable.class)
    public UserEntity getUserByName(String username) {
        List<UserEntity> list = userService.list(
                new QueryWrapper<UserEntity>()
                        .eq("deleted", false)
                        .eq("username", username)
        );
        if (CollectionUtil.isNotEmpty(list) && list.size() == 1) {
            return list.get(0);
        }
        return null;
    }

    @Transactional(rollbackFor = Throwable.class)
    public SResponse<Boolean> outletAdd(UserOutletSaveDto saveDto) {
        UserEntity userEntity = UserOutletSaveDto.converted(saveDto);
        userEntity.setOutletId(CurrentUserCache.getOutletId());
        // 校验用户名是否重复
        List<UserEntity> checkList = userService.list(new QueryWrapper<UserEntity>().eq("deleted", false)
                .eq("username", saveDto.getUsername()));
        if (CollectionUtil.isNotEmpty(checkList)) {
            return SResponse.fail(Constant.ERRCODE_PARAM, "用户名已存在，添加失败");
        }

        userEntity.setPassword(BCryptUtils.createInitPassword());
        userEntity.setCreateUser(CurrentUserCache.getUserId());
        userService.save(userEntity);

        userRoleService.saveUserRoles(userEntity.getUserId(), saveDto.getRoleIds());

        return SResponse.ok(Boolean.TRUE);

    }

    @Transactional(rollbackFor = Throwable.class)
    public SResponse<Boolean> add(UserSaveDto saveDto) {
        UserEntity userEntity = UserSaveDto.converted(saveDto);

        dealwithRoleRelation(userEntity, saveDto.getRoleIds());

        // 校验用户名是否重复
        List<UserEntity> checkList = userService.list(new QueryWrapper<UserEntity>().eq("deleted", false)
                .eq("username", saveDto.getUsername()));
        if (CollectionUtil.isNotEmpty(checkList)) {
            return SResponse.fail(Constant.ERRCODE_PARAM, "用户名已存在，添加失败");
        }

        userService.save(userEntity);

        userRoleService.saveUserRoles(userEntity.getUserId(), saveDto.getRoleIds());

        return SResponse.ok(Boolean.TRUE);
    }

    /**
     * 根据用户角色处理所属门店信息
     *
     * @author Gzhao 2021/2/6
     * @param
     * @return
     */
    private void dealwithRoleRelation(UserEntity userEntity, List<Integer> roleIds) {
        // 当前角色为系统管理员
        if (CurrentUserCache.getOutletId() == 0){
            // 所选角色为系统管理员
            if (roleIds.contains(2)) {
                userEntity.setOutletId(0);
            }
            // 所选角色为商城管理员
            else if (roleIds.contains(3)) {
                userEntity.setOutletId(1);
            }
        }
        // 当前用户为商城用户（或门店用户）
        else if (CurrentUserCache.getOutletId() >= 1) {
            userEntity.setOutletId(CurrentUserCache.getOutletId());
        }
    }

    public SResponse<Boolean> deleteById(Integer userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setDeleted(true);
        userEntity.setUpdateUser(CurrentUserCache.getUserId());

        boolean re = userService.update(
                userEntity,
                new UpdateWrapper<UserEntity>()
                        .eq("user_id", userId)
                        .eq("deleted", false)
        );
        if (re) {
            return SResponse.ok(Boolean.TRUE);
        }
        return SResponse.fail(Constant.ERRCODE_DATABASE_OPERATION, "用户不存在，删除失败");
    }

    public SResponse<Boolean> edit(UserUpdateDto updateDto) {
        UserEntity userEntity = UserUpdateDto.converted(updateDto);

        dealwithRoleRelation(userEntity, updateDto.getRoleIds());

        boolean re = userService.update(
                userEntity,
                new UpdateWrapper<UserEntity>()
                        .eq("user_id", updateDto.getUserId())
                        .eq("deleted", false)
        );
        if (re) {
            userRoleService.saveUserRoles(userEntity.getUserId(), updateDto.getRoleIds());
            return SResponse.ok();
        }
        return SResponse.fail(Constant.ERRCODE_DATABASE_OPERATION, "用户不存在，编辑失败");
    }

    public SResponse<PageRespBase<UserPageVo>> getPageList(UserQueryDto queryDto) {
        // 开启分页
        Page page = PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());

        if (CurrentUserCache.getOutletId() > 0){
            queryDto.setOutletId(CurrentUserCache.getOutletId());
        }
        List<UserPageVo> reList = userService.getPageList(queryDto);

        PageRespBase<UserPageVo> re = PageRespBase.create(page, reList);
        PageHelper.clearPage();
        return SResponse.ok(re);
    }

    public SResponse<Boolean> changeStatusById(Integer userId, boolean status) {
        UserEntity userEntity = new UserEntity();
        userEntity.setStatus(status);
        userEntity.setUpdateUser(CurrentUserCache.getUserId());

        boolean re = userService.update(
                userEntity,
                new UpdateWrapper<UserEntity>()
                        .eq("user_id", userId)
                        .eq("deleted", false)
        );
        if (re) {
            return SResponse.ok();
        }
        return SResponse.fail(Constant.ERRCODE_DATABASE_OPERATION, "用户不存在，操作失败");
    }

    public SResponse<UserPermissionVo> getPermissionInfo() {
        UserPermissionDto userPermissionDto = userService.getPermissionInfo(CurrentUserCache.getUserId());
        return SResponse.ok(UserPermissionVo.create(userPermissionDto));
    }

    public void obtainCurrentInfo() {
        UserEntity currentUser = userService.getById(SecurityUtil.getCurrentUserId());
        OutletInfoEntity outletInfo = outletInfoService.getById(currentUser.getOutletId());

        String outletName = "-";
        Character outletMark = '-';
        if (ObjectUtil.isNotNull(outletInfo)) {
            if (outletInfo.getId() > 1 && CharUtil.isBlankChar(outletInfo.getMark())) {
                throw new OutletBusinessException("门店订单标记信息未维护");
            }
            outletName = outletInfo.getName();
            outletMark = outletInfo.getMark();
        }

        CurrentUserCache.init(currentUser.getUserId(), currentUser.getUsername(), currentUser.getOutletId(),
                outletName, outletMark);
    }

    public SResponse<PageRespBase<UserPageVo>> getOutletPageList(UserQueryDto queryDto) {
        queryDto.setOutletId(CurrentUserCache.getOutletId());

        // 开启分页
        Page page = PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());

        List<UserPageVo> reList = userService.getPageList(queryDto);

        PageRespBase<UserPageVo> re = PageRespBase.create(page, reList);
        PageHelper.clearPage();

        return SResponse.ok(re);
    }

    public SResponse<Boolean> initPasswrod(Integer userId) {
        UserEntity user = userService.getById(userId);
        user.setPassword(BCryptUtils.createInitPassword());
        user.setUpdateUser(CurrentUserCache.getUserId());

        userService.updateById(user);
        return SResponse.ok(Boolean.TRUE);
    }

    public SResponse<Boolean> udpatePassword(UserUpdatePasswordDto updateDto) {
        UserEntity user = userService.getById(CurrentUserCache.getUserId());

        UserEntity updateUser = new UserEntity();
        updateUser.setUserId(user.getUserId());
        updateUser.setPassword(BCryptUtils.encodePassword(updateDto.getPassword()));

        userService.updateById(updateUser);
        return SResponse.ok(Boolean.TRUE);
    }

    public SResponse<List<UserSelectVo>> getUserListByRoleId(Integer roleId) {
        List<UserSelectVo> rs = userService.getUserListByRoleId(roleId);
        return SResponse.ok(rs);
    }
}
